﻿
namespace HSS.Xaml.UI.Controls
{
	#region Using Directives
	using System.Collections.Generic;
	using System.Windows;
	using System.Windows.Controls;
	using HSS.ComponentModel;

	#endregion

	#region AutoCompleteBoxEditorBase
	/// <summary>
	/// AutoCompleteBoxEditorBase provides an AutoCompleteBox as the editor for a Property
	/// </summary>
	public abstract class AutoCompleteBoxEditorBase : PropertyGridEditor
	{
		#region Constructors
		/// <summary>
		/// Constructor
		/// </summary>
		/// <param name="descriptor">The HSSPropertyDescriptor to edit</param>
		protected AutoCompleteBoxEditorBase(HSSPropertyDescriptor descriptor)
			: base(descriptor)
		{
		}
		#endregion

		#region Properties
		/// <summary>
		/// Gets the Control
		/// </summary>
		public AutoCompleteComboBox Control
		{
			get { return (AutoCompleteComboBox)this.InlineEditControl; }
		}
		#endregion

		#region Overrides
		/// <summary>
		/// Creates the Inline Editor control.
		/// </summary>
		/// <returns>The control as a FrameworkElement.</returns>
		protected override FrameworkElement CreateInlineEditControl()
		{
			AutoCompleteComboBox box = new AutoCompleteComboBox();
			box.ItemTemplate = ControlUtil.CreateDataTemplate(typeof(TextBlock), "ObjectDisplay");

			AutoCompleteFilterPredicate<object> itemFilter = this.GetItemFilter();
			if (null != itemFilter)
				box.ItemFilter = itemFilter;

			AutoCompleteFilterPredicate<string> textFilter = this.GetTextFilter();
			if (null != textFilter)
				box.TextFilter = textFilter;

			return box;
		}
		/// <summary>
		/// Perform additional Inline Edit Control initialization.
		/// </summary>
		protected override void InitializeInlineEditControl()
		{
			base.InitializeInlineEditControl();
			IEnumerable<object> listItems = this.GetListItems();
			this.LoadItems(listItems);
		}
		/// <summary>
		/// Updates the editor with the new value.
		/// </summary>
		/// <param name="newValue">The new value.</param>
		protected override void UpdateInlineEditControl(object newValue)
		{
			Guard.ArgumentNotNull(newValue, "newValue");
			this.Control.Text = newValue.ToString();
		}
		/// <summary>
		/// Gets the current value held by the control.
		/// </summary>
		/// <returns>The object.</returns>
		protected override object GetControlValue()
		{
			if (null == this.Control.SelectedItem)
				return null;
			return ((ComboBoxItemObject)this.Control.SelectedItem).ObjectValue;
		}
		/// <summary>
		/// Begin the editing process.
		/// </summary>
		protected override void OnBeginEdit()
		{
			base.OnBeginEdit();
			this.Control.DropDownClosed += new RoutedPropertyChangedEventHandler<bool>(this.Control_DropDownClosed);
		}
		/// <summary>
		/// End the editing process.
		/// </summary>
		protected override void OnEndEdit()
		{
			base.OnEndEdit();
			this.Control.DropDownClosed -= new RoutedPropertyChangedEventHandler<bool>(this.Control_DropDownClosed);
		}
		#endregion

		#region Methods
		/// <summary>
		/// Populate the List of Items available
		/// </summary>
		/// <param name="items">IEnumerable List Objects</param>
		protected virtual void LoadItems(IEnumerable<object> items)
		{
			Guard.ArgumentNotNull(items, "items");
			var Items = new List<ComboBoxItemObject>();
			foreach (var item in items)
				Items.Add(new ComboBoxItemObject(item.ToString(), item));
			this.Control.ItemsSource = Items;
		}
		/// <summary>
		/// When overridden returns back the customer Item filter
		/// </summary>
		/// <returns>The custom AutoCompleteFilterPredicate for Objects</returns>
		[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate")]
		protected virtual AutoCompleteFilterPredicate<object> GetItemFilter()
		{
			return null;
		}
		/// <summary>
		/// When overridden returns back the customer Text filter
		/// </summary>
		/// <returns>The custom AutoCompleteFilterPredicate for Strings</returns>
		[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate")]
		protected virtual AutoCompleteFilterPredicate<string> GetTextFilter()
		{
			return null;
		}
		#endregion

		#region Event Handlers
		void Control_DropDownClosed(object sender, RoutedPropertyChangedEventArgs<bool> e)
		{
			this.EndEdit();
		}
		#endregion

		#region Abstract
		/// <summary>
		/// Retrieve the list of available objects for the ComboBox
		/// </summary>
		/// <returns></returns>
		[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate")]
		protected abstract IEnumerable<object> GetListItems();
		#endregion
	}
	#endregion
}
